﻿using BPMN.Application.IService;
using BPMN.Domain;
using BPMN.Domain.Entity.User;
using BPMN.Domain.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using BPMN.DomianShare;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using BPMN.Application.Contracts.DTO.Response.UserInfo;
using BPMN.Application.Contracts.DTO.Response;
using BPMN.Application.Contracts.DTO.Response.Role;
using BPMN.Application.Contracts.DTO.Response.Permission;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using BPMN.Application.Contracts.DTO.Request.UserInfo;
using BPMN.Application.Contracts.DTO.Response.RolePermission;

namespace BPMN.Application.Service
{
    public class UserAppService : AppServiceBase<UserInfo>, IUserAppService
    {
        private readonly IRepositoryBase<UserInfo> RepUser;
        private readonly IRepositoryBase<UserRole> RepUserRole;
        private readonly IRepositoryBase<Role> RepRole;
        private readonly IRepositoryBase<Permission> RepPer;
        private readonly IRepositoryBase<RolePermission> RepPerRole;
        private readonly IMapper mapper;
        public IRepositoryBase<Extend> Extend { get; }
        public IRepositoryBase<Attributes> Attr { get; }

        public UserAppService(IRepositoryBase<UserInfo> RepUser, IRepositoryBase<UserRole> RepUserRole, IRepositoryBase<Role> RepRole, IMapper mapper, IRepositoryBase<Permission> RepPer, IRepositoryBase<RolePermission> RepPerRole, IRepositoryBase<Extend> extend, IRepositoryBase<Attributes> attr) : base(RepUser)
        {
            this.RepUser = RepUser;
            this.RepUserRole = RepUserRole;
            this.RepRole = RepRole;
            this.mapper = mapper;
            this.RepPer = RepPer;
            this.RepPerRole = RepPerRole;
            Extend = extend;
            Attr = attr;
        }
        /// <summary>
        ///  用户添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<int>> AddUserInfo(UserInfoRequestDto entity)
        {
            var slist = await (await RepUser.GetAll()).FirstOrDefaultAsync(x => x.UserName == entity.UserName && x.IsDel == true);
            if (slist != null)
            {
                return new ResultResponseDto<int>(ResultCode.Fail, "用户名已存在!");
            }
            try
            {
                RepUser.BeginTran();
                //先添加用户表
                var obj = mapper.Map<UserInfo>(entity);
                await RepUser.Add(obj);
                int UserId = obj.UserId;
                var RoleIdArr = entity.RoleIds.Split(',');

                foreach (var item in RoleIdArr)
                {
                    UserRole userRole = new UserRole();
                    userRole.UserId = UserId;
                    userRole.RoleId = int.Parse(item);
                    await RepUserRole.Add(userRole);
                }
                RepUser.CommitTran();
                return new ResultResponseDto<int>();

            }
            catch (Exception)
            {
                RepUser.RollBackTran();
                throw;
            }
        }
        /// <summary>
        /// 用户显示功能
        /// </summary>
        /// <returns></returns>
        public async Task<ResultResponseDto<List<UserInfoShowResponseDto>>> GetUserInfo()
        {
            var slist = from A in RepUser.GetAll().Result.ToList()
                        where (A.IsDel == true)
                        select new UserInfoShowResponseDto()
                        {
                            UserId = A.UserId,
                            UserName = A.UserName,
                            Name = A.Name,
                            Tel = A.Tel,
                            Email = A.Email,
                            UserDate = A.UserDate,
                            IsDel = A.IsDel,
                            RoleList = (from B in RepRole.GetAll().Result.ToList()
                                        join C in RepUserRole.GetAll().Result.ToList()
                                        on B.Id equals C.RoleId
                                        where (C.UserId == A.UserId)
                                        select new RoleShowResponseDto()
                                        {
                                            Id = B.Id,
                                            Name = B.Name,
                                        }).ToList()
                        };
            return new ResultResponseDto<List<UserInfoShowResponseDto>>()
            {
                Code = ResultCode.Ok,
                ErrorInfo = "获取成功",
                Data = mapper.Map<List<UserInfoShowResponseDto>>(slist)

            };
        }
        /// <summary>
        /// 根据Id获取用户信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<UserInfoShowResponseDto>> GetUserInfoById(int Id)
        {
            var slist = from A in RepUser.GetAll().Result.ToList()
                        where (A.IsDel == true && A.UserId == Id)
                        select new UserInfoShowResponseDto()
                        {
                            UserId = A.UserId,
                            UserName = A.UserName,
                            Name = A.Name,
                            Tel = A.Tel,
                            Email = A.Email,
                            UserDate = A.UserDate,
                            IsDel = A.IsDel,
                            RoleList = (from B in RepRole.GetAll().Result.ToList()
                                        join C in RepUserRole.GetAll().Result.ToList()
                                        on B.Id equals C.RoleId
                                        where (C.UserId == A.UserId)
                                        select new RoleShowResponseDto()
                                        {
                                            Id = B.Id,
                                            Name = B.Name,
                                        }).ToList()
                        };
            return new ResultResponseDto<UserInfoShowResponseDto>()
            {
                Code = ResultCode.Ok,
                ErrorInfo = "获取成功",
                Data = mapper.Map<UserInfoShowResponseDto>(slist.FirstOrDefault())

            };
        }
        /// <summary>
        /// 修改功能
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<int>> UpdateUserInfo(UserInfoRequestDto entity)
        {
            try
            {
                RepUser.BeginTran();
                var slist = await RepUser.Get(entity.UserId);
                slist.Name = entity.Name;
                slist.Tel = entity.Tel;
                slist.Email = entity.Email;

                await RepUser.Update(slist);

                var RoleUserList = RepUserRole.GetAll().Result.Where(x => x.UserId == entity.UserId);

                await RepUserRole.RealDel(RoleUserList.AsEnumerable());

                var RoleIdArr = entity.RoleIds.Split(',');

                List<UserRole> userRole = new List<UserRole>();
                foreach (var item in RoleIdArr)
                {
                    userRole.Add(new UserRole { UserId = entity.UserId, RoleId = int.Parse(item) });

                }
                await RepUserRole.AddRange(userRole);
                RepUser.CommitTran();
                return new ResultResponseDto<int>();

            }
            catch (Exception)
            {
                RepUser.RollBackTran();
                throw;
            }
        }
        /// <summary>
        /// 用户删除功能
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<int>> DeleleUserInfo(int UserId)
        {
            try
            {
                RepUser.BeginTran();

                await RepUser.Delete(UserId);

                var RoleUserList = RepUserRole.GetAll().Result.Where(x => x.UserId == UserId);

                await RepUserRole.RealDel(RoleUserList.AsEnumerable());
                RepUser.CommitTran();
                return new ResultResponseDto<int>();

            }
            catch (Exception)
            {
                RepRole.RollBackTran();
                throw;
            }
        }
        /// <summary>
        /// 登录功能
        /// </summary>
        /// <param name="UserName"></param>
        /// <param name="Pwd"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<int>> LoginAction(string UserName, string Pwd)
        {
            var slist = RepUser.GetAll().Result.Where(x => x.UserName == UserName && x.Pwd == Pwd && x.IsDel == true).FirstOrDefault();
            if (slist != null)
            {
                return new ResultResponseDto<int>()
                {
                    Code = ResultCode.Ok,
                    ErrorInfo = "登录成功",
                    Data = slist.UserId,
                    Token = this.CreateTokenString()
                };
            }
            else
            {
                return new ResultResponseDto<int>()
                {
                    Code = ResultCode.Fail,
                    ErrorInfo = "登录失败"
                };
            }
        }
        /// <summary>
        /// 生成 JWT Token（令牌）
        /// </summary>
        /// <returns></returns>
        private string CreateTokenString()
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: "BeiJingBW",
                audience: "BeiJingBW",
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
        /// <summary>
        /// 菜单列表显示
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public async Task<ResultResponseDto<List<TreeDtoResponse>>> PermissionListShow(int UserId)
        {
            var query = (from user in RepUser.GetAll().Result.ToList()
                         join userRole in RepUserRole.GetAll().Result.ToList()
                         on user.UserId equals userRole.UserId
                         join role in RepRole.GetAll().Result.ToList()
                         on userRole.RoleId equals role.Id
                         join rolePermission in RepPerRole.GetAll().Result.ToList()
                         on role.Id equals rolePermission.RoleId
                         join permission in RepPer.GetAll().Result.ToList()
                         on rolePermission.PermissionId equals permission.Id
                         where (user.UserId == UserId)
                         group permission by new
                         {
                             permission.Name,
                             permission.Pid,
                             permission.URL,
                             permission.Id,
                         } into G
                         select new UserRolePermissionShowDto
                         {
                             PerName = G.Key.Name,
                             PerId = G.Key.Id,
                             Pid = G.Key.Pid,
                             URL = G.Key.URL,
                         }).ToList();
            return new ResultResponseDto<List<TreeDtoResponse>>()
            {
                Code = ResultCode.Ok,
                ErrorInfo = "获取成功",
                Data = GetRerTree(query, 0)
            };
        }
        /// <summary>
        /// 树形结构
        /// </summary>
        /// <param name="list"></param>
        /// <param name="Pid"></param>
        /// <returns></returns>
        private List<TreeDtoResponse> GetRerTree(List<UserRolePermissionShowDto> list, int Pid)
        {
            var slist = list.Where(x => x.Pid == Pid).ToList();
            var result = from A in slist
                         select new TreeDtoResponse
                         {
                             value = A.PerId,
                             label = A.PerName,
                             URL = A.URL,
                             children = GetRerTree(list, A.PerId)
                         };
            return result.Count() == 0 ? null : result.ToList();
        }



        /// <summary>
        /// 角色权限显示功能
        /// </summary>
        /// <returns></returns>
        public async Task<ResultResponseDto<RolePermissionResponseShowDto>> GetRolePeimiss(int UserId,int? PermId)
        {

            var list = (from a in RepUserRole.GetAll().Result.ToList()
                        join b in RepPerRole.GetAll().Result.ToList()
                        on a.RoleId equals b.RoleId
                        where a.UserId == UserId
                        select b).ToList();

            if(PermId!= null)
            {
                list = list.Where(x=>x.PermissionId == PermId).ToList();
            }

            var slist = list.FirstOrDefault();

            return new ResultResponseDto<RolePermissionResponseShowDto>()
            {
                Code = ResultCode.Ok,
                ErrorInfo = "获取成功",
                Data = mapper.Map<RolePermissionResponseShowDto>(slist)
            };
        }




       
    }
}